package com.godating.foaf.repository;

import java.util.HashSet;
import java.util.Set;

import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.traversal.Evaluators;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.kernel.Traversal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.godating.foaf.domain.Person;
import com.godating.foaf.domain.SnsProvider;

@Repository
public class FoafRepository {
	
	private static final String ACCOUNT_ID = "accountId";
	
	@Autowired
	private PersonGraphRepository  personGraphRepository;
  
	public void deletePerson(long accountId) {
		Person person=personGraphRepository.findByPropertyValue(ACCOUNT_ID, accountId);
		if(person!=null)
		{
			person.remove();
		}
	}
	
	public void updateFriends(long accountId, SnsProvider snsProvider,
			Set<Long> friendIds) {
		Person person=createPersonIfNotExist(accountId);
		Node personNode=person.getPersistentState();
		Set<Long> set= new HashSet<Long>();
		for(Relationship relationship:personNode.getRelationships(snsProvider))
		{
			Long l=(Long)relationship.getOtherNode(personNode).getProperty(ACCOUNT_ID);
			if(friendIds.contains(l))
			{
				set.add(l);
			}
			else
			{
				relationship.delete();
			}
		}
		friendIds.removeAll(set);
		for(long l:friendIds)
		{
			Person p=createPersonIfNotExist(l);
			person.relateTo(p, snsProvider.name());
		}
	}

	public Set<Long> getFoaf( long accountId,SnsProvider snsProvider, int depth) {
		TraversalDescription td = Traversal.description().breadthFirst()
				.relationships(snsProvider)
				.evaluator(Evaluators.atDepth(depth))
				.evaluator(Evaluators.excludeStartPosition());
		Person person = personGraphRepository.findByPropertyValue(ACCOUNT_ID, accountId);
		Set<Long> accountIds=new HashSet<Long>();
		for (Person friend : personGraphRepository.findAllByTraversal(person,td)) {
			accountIds.add(friend.getAccountId());
		}
		return accountIds;
	}
	
	private Person createPersonIfNotExist(long accountId) {
		Person person=personGraphRepository.findByPropertyValue(ACCOUNT_ID, accountId);
		if(person==null)
		{
			person=new Person();
			person.setAccountId(accountId);
			person.persist();
		}	
		return person;
	}

}
